package com.c2b.algorithm.leetcode.base;

/**
 * <a href='https://leetcode.cn/problems/bulls-and-cows/'>猜数字游戏(Bulls and Cows)</a>
 * <p>你在和朋友一起玩 猜数字（Bulls and Cows）游戏，该游戏规则如下：</p>
 * <p>
 *     写出一个秘密数字，并请朋友猜这个数字是多少。朋友每猜测一次，你就会给他一个包含下述信息的提示：
 *     <ul>
 *         <li>猜测数字中有多少位属于数字和确切位置都猜对了（称为 "Bulls"，公牛），</li>
 *         <li>有多少位属于数字猜对了但是位置不对（称为 "Cows"，奶牛）。也就是说，这次猜测中有多少位非公牛数字可以通过重新排列转换成公牛数字。</li>
 *         <li></li>
 *     </ul>
 * </p>
 * <p>给你一个秘密数字 secret 和朋友猜测的数字 guess ，请你返回对朋友这次猜测的提示。</p>
 * <p>提示的格式为 "xAyB" ，x 是公牛个数， y 是奶牛个数，A 表示公牛，B 表示奶牛。</p>
 * <p>请注意秘密数字和朋友猜测的数字都可能含有重复数字。</p>
 *
 * <p>
 * <b>示例：</b>
 * <pre>
 * 示例 1：
 *      输入：secret = "1807", guess = "7810"
 *      输出："1A3B"
 *      解释：数字和位置都对（公牛）用 '|' 连接，数字猜对位置不对（奶牛）的采用斜体加粗标识。
 *          "1807"
 *            |
 *          "7810"
 *
 * 示例 2：
 *      输入：secret = "1123", guess = "0111"
 *      输出："1A1B"
 *      解释：数字和位置都对（公牛）用 '|' 连接，数字猜对位置不对（奶牛）的采用斜体加粗标识。
 *          "1123"        "1123"
 *            |      or     |
 *          "0111"        "0111"
 *          注意，两个不匹配的 1 中，只有一个会算作奶牛（数字猜对位置不对）。通过重新排列非公牛数字，其中仅有一个 1 可以成为公牛数字。
 * </pre>
 * </p>
 * <p>
 * <b>提示：</b>
 *     <ul>
 *         <li>1 <= secret.length, guess.length <= 1000</li>
 *         <li>secret.length == guess.length</li>
 *         <li>secret 和 guess 仅由数字组成</li>
 *     </ul>
 * </p>
 *
 * @author c2b
 * @since 2023/12/15 11:23
 */
public class LC0299BullsAndCows_M {
    static class Solution {
        public String getHint(String secret, String guess) {
            // 公牛，需要满足数字和确切位置都猜对；统计满足 secret[i]=guess[i] 的下标个数，即为公牛的个数
            int bulls = 0;
            // secretCnt、guessCnt 用于统计位置不同的各个数字出现的次数
            // 奶牛，需要满足数字猜对但是位置不对;可以在 secret[i]≠guess[i] 时，分别统计 secret 和 guess 的各个字符的出现次数，记在两个长度为 10 的数组中。
            int[] secretCnt = new int[10];
            int[] guessCnt = new int[10];
            for (int i = 0; i < secret.length(); i++) {
                if (secret.charAt(i) == guess.charAt(i)) {
                    ++bulls;
                } else {
                    ++secretCnt[secret.charAt(i) - '0'];
                    ++guessCnt[guess.charAt(i) - '0'];
                }
            }
            int cows = 0;
            for (int i = 0; i < 10; i++) {
                cows += Math.min(secretCnt[i], guessCnt[i]);
            }
            return bulls + "A" + cows + "B";
        }
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        System.out.println(solution.getHint("1807", "7810"));
        System.out.println(solution.getHint("1123", "0111"));
    }
}
